#ifndef ARBOLBMAS_H_
#define ARBOLBMAS_H_

#include <vector>
#include <iostream>
#include "Nodo.h"
#include "NodoHoja.h"
#include "NodoInterno.h"
#include <algorithm>
#include "../Archivos/ArchivoDeEstructurasFijas.h"
#include "../Archivos/ManejadorEstructurasLibres.h"
#include "../Entidades/Utils.h"
#include "../Archivos/Configuracion.h"
using namespace std;
using namespace Archivos;
using namespace Entidades;

namespace Arboles {

class ArbolBMas {

private:
	unsigned int capacidadMaximaNodosInternos;
	unsigned int capacidadMinimaNodosInternos;
	unsigned int capacidadMaximaNodosHoja;
	unsigned int capacidadMinimaNodosHoja;
	ArchivoDeEstructurasFijas* archivoNodos;
	ManejadorEstructurasLibres* nodosLibres;
	Nodo* raiz;
	RegistroArbol* ultimoElementoLeido;

	Utils::ResultadoOperacionArbol suprimirInterno(Nodo* nodo, RegistroArbol* registro);
	Utils::ResultadoOperacionArbol insertarInterno(Nodo* nodo, RegistroArbol* dato);
	Utils::ResultadoOperacionArbol balancearNodos(Nodo* hermanoIzquierdo, Nodo* hermanoDerecho);
	Utils::ResultadoOperacionArbol balancearRaiz(Nodo* raiz, Nodo* hijoIzquierdo, Nodo* hijoDerecho);
	void llenarNodoCon(Nodo* nodoALlenar, unsigned int numeroDeNodoAVaciar, unsigned int nivelDeNodoAVaciar);
	void actualizarNodo(Nodo *nodo);

	void preOrder(Nodo* nodo);
	void escribirEnARchivo(Nodo* nodo);

	unsigned int getNumeroNodoHojaPorClave(Nodo* nodo, string clave);
	RegistroArbol* getRegistroMasChicoEnArbol(Nodo* nodo);

public:

	ArbolBMas(string nombre);

	void suprimir(string clave, unsigned int dato);
	void insertar(string clave, unsigned int dato);
	void modificar(string clave, unsigned int dato, unsigned int datoNuevo);

	RegistroArbol* siguiente();
	IRegistroIndice* buscar(string clave);
	void exportar();

	void getNodo(Nodo *nodo);
	unsigned int crearNodoNuevo(Nodo *nodoACrear);

	virtual ~ArbolBMas();

};

}

#endif
